package net.fkzg.framework.application;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import net.fkzg.framework.application.data.StorageDataHelper;
import net.fkzg.framework.application.datasource.JdbcConfig;
import net.fkzg.framework.application.dingtalk.DingTalkConfig;
import net.fkzg.framework.application.dingtalk.DingTalkHelper;
import net.fkzg.framework.application.token.CustomBase62;
import net.fkzg.framework.application.token.CustomToken;
import net.fkzg.framework.application.token.CustomTokenUtils;
import net.fkzg.framework.application.vo.TokenWrap;
import net.fkzg.framework.application.vo.UserInfo;
import org.smartboot.http.common.Cookie;
import org.smartboot.http.common.enums.HttpStatus;
import org.smartboot.http.common.utils.StringUtils;
import org.smartboot.http.restful.RestResult;
import org.smartboot.http.restful.annotation.*;
import org.smartboot.http.server.HttpRequest;
import org.smartboot.http.server.HttpResponse;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Map;

import static net.fkzg.framework.util.Constant.SUPER_ID;
import static net.fkzg.framework.util.Constant.SUPER_TYPE;

@Slf4j
@Controller(value = "api")
public class ApiRestController {

    @RequestMapping(value = "getTokenByAccount", method = RequestMethod.GET)
    public RestResult<?> getTokenByAccount(@Param("account") String account, @Param("pwd") String pwd) throws Exception {
        log.info("管理员：使用账号:{} 密码hash:{}登录系统", account, pwd);
        if (ApplicationInitializer.checkSuperUser(account, pwd)) {
            String token = CustomTokenUtils.saveToken(SUPER_ID, SUPER_TYPE, 120);
            long expiresAtStamp = LocalDateTime.now().plusMinutes(120).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            return RestResult.ok(TokenWrap.of(token).setExpiresAtStamp(expiresAtStamp));
        }
        return RestResult.fail("用户名或密码错误");
    }

    @Interceptor(patterns = "/api/**", exclude = {"/api/getTokenByAccount"})
    public RestResult<?> checkAuth(HttpRequest request, HttpResponse response) throws Exception {
        boolean isAuth = false;
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if ("token".equals(cookie.getName())) {
                String token = cookie.getValue();
                CustomToken customToken = CustomTokenUtils.getToken(token);
                if (null != customToken && customToken.getUserId().equals(SUPER_ID) && customToken.getUserType().equals(SUPER_TYPE)) {
                    isAuth = true;
                }
            }
        }
        if (!isAuth) {
            response.setHttpStatus(HttpStatus.OK);
            RestResult<Object> fail = RestResult.fail("未登录或已超时");
            fail.setCode(403);
            return fail;
        }
        return null;
    }

    @RequestMapping("getUserInfo")
    public RestResult<?> getUserInfo() throws Exception {
        return RestResult.ok(UserInfo.of("超级管理员"));
    }

    @RequestMapping(value = "saveDinkTalkConfig", method = RequestMethod.POST)
    public RestResult<?> saveDinkTalkConfig(DingTalkConfig config) throws Exception {
        log.info("saveDinkTalkConfig:{}", JSONObject.toJSONString(config));
        if (StringUtils.isNotBlank(config.getId())) {
            if (StorageDataHelper.notExistData(config.getId(), DingTalkConfig.class)) {
                return ApplicationInitializer.returnException(400, "ID不存在");
            }
        } else {
            config.setId(CustomBase62.genTimeStampId());
        }
        StorageDataHelper.saveData(config.getId(), config);
        return RestResult.ok(null);
    }

    @RequestMapping("getDinkTalkConfigList")
    public RestResult<?> getConfigList() throws Exception {
        Map<String, DingTalkConfig> map = StorageDataHelper.getDataMap(DingTalkConfig.class);
        return RestResult.ok(map.values());
    }

    @RequestMapping("sendDingTalkTest")
    public RestResult<?> sendDingTalkTest(@Param("id") String id, @Param("msg") String msg) throws Exception {
        StorageDataHelper.getDataById(id, DingTalkConfig.class).ifPresent(config -> {
            DingTalkHelper.sendMsgToDingTalk(config.getWebhook(), config.getKeyword(), "测试内容如下", msg);
        });
        return RestResult.ok(null);
    }

    @RequestMapping(value = "saveMysqlConfig", method = RequestMethod.POST)
    public RestResult<?> saveMysqlConfig(JdbcConfig config) throws Exception {
        log.info("saveMysqlConfig:{}", JSONObject.toJSONString(config));
        if (StringUtils.isNotBlank(config.getId())) {
            if (StorageDataHelper.notExistData(config.getId(), JdbcConfig.class)) {
                return ApplicationInitializer.returnException(400, "ID不存在");
            }
        } else {
            config.setId(CustomBase62.genTimeStampId());
        }
        StorageDataHelper.saveData(config.getId(), config);
        return RestResult.ok(null);
    }

    @RequestMapping("getMysqlConfigList")
    public RestResult<?> getMysqlConfigList() throws Exception {
        Map<String, JdbcConfig> map = StorageDataHelper.getDataMap(JdbcConfig.class);
        return RestResult.ok(map.values());
    }

    @RequestMapping("sendMysqlTest")
    public RestResult<?> sendMysqlTest(@Param("id") String id, @Param("msg") String msg) throws Exception {
        StorageDataHelper.getDataById(id, JdbcConfig.class).ifPresent(config -> {
            log.info("测试数据库联通特性");
        });
        return RestResult.ok(null);
    }

}
